//===-- HelloWorld.cpp - Example Transformations --------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "EncodeFunctionName2.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/Pass.h"
#include "llvm/Passes/PassBuilder.h"
#include "llvm/Passes/PassPlugin.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/raw_ostream.h"
#include <limits>
#include <random>

using namespace llvm;

EncodeFunctionNamePass2::EncodeFunctionNamePass2() {
  std::random_device Rd;  // 用于获取随机种子
  std::mt19937 Gen(Rd()); // 使用随机种子初始化一个随机数生成器
  // 获取int的最大值
  int MaxInt = std::numeric_limits<int>::max();
  // 获取int的最小值
  int MinInt = std::numeric_limits<int>::min();
  std::uniform_int_distribution<> Dis(MinInt, MaxInt); // 定义一个在1到100之间的均匀分布
  RandomId = Dis(Gen); // 生成一个随机数
}

PreservedAnalyses EncodeFunctionNamePass2::run(Function &F,
                                      FunctionAnalysisManager &AM) {
  // 获取当前函数名
  StringRef OldName = F.getName();

  errs() << "Ecode2 " << OldName << "\n";
  // 构造新名字（例如，在原名字前加前缀 "renamed_"）
  if (F.getName().compare("main") != 0) {
    std::string NewFunctionName;
    genNewFunctionName(F, NewFunctionName);
    F.setName(NewFunctionName);
  }
//  F.setName(newName);
  return PreservedAnalyses::all();
}

void EncodeFunctionNamePass2::genNewFunctionName(
    Function &F, std::string& NewFunctionName) {
  // 获取当前函数名
//  StringRef OldName = F.getName();
//
//  // 构造新名字（例如，在原名字前加前缀 "renamed_"）
//  std::string NewName = ("renamed_" + OldName).str();
//  NewName += RandomId;
//
//  llvm::MD5 Hasher;
//  llvm::MD5::MD5Result Hash;
//  Hasher.update(NewName);
//  Hasher.final(Hash);
//  NewFunctionName = llvm::utohexstr(Hash.low(), /*LowerCase=*/true);
}

/* New PM Registration */
llvm::PassPluginLibraryInfo getByePluginInfo() {
    return {LLVM_PLUGIN_API_VERSION, "EncodeFunctionName2", LLVM_VERSION_STRING,
            [](PassBuilder &PB) {
                PB.registerVectorizerStartEPCallback(
                        [](llvm::FunctionPassManager &PM, OptimizationLevel Level) {
                            PM.addPass(EncodeFunctionNamePass2());
                        });
                PB.registerPipelineParsingCallback(
                        [](StringRef Name, llvm::FunctionPassManager &PM,
                           ArrayRef<llvm::PassBuilder::PipelineElement>) {
                            if (Name == "encode-function-name2") {
                                PM.addPass(EncodeFunctionNamePass2());
                                return true;
                            }
                            return false;
                        });
            }};
}

extern "C" LLVM_ATTRIBUTE_WEAK ::llvm::PassPluginLibraryInfo
llvmGetPassPluginInfo() {
//    return getByePluginInfo();

    return {LLVM_PLUGIN_API_VERSION, "SimplifyCFG222", LLVM_VERSION_STRING,
            [](PassBuilder &PB) {
                PB.registerPipelineParsingCallback(
                        [](StringRef Name, llvm::FunctionPassManager &PM,
                           ArrayRef<llvm::PassBuilder::PipelineElement>) {
                            if (Name == "tut-simplifycfg222") {
                                PM.addPass(EncodeFunctionNamePass2());
                                return true;
                            }
                            return false;
                        });
            }};
}